// Monad之 IO 函子问题: 函子嵌套

const fp = require('lodash/fp')
const fs = require('fs')

class IO {
    static of (value){
        return new IO(function(){
            return value
        })
    }
    constructor (fn) {
        this._value = fn 
    }
    map(fn) {
        return new IO(fp.flowRight(fn, this._value))
    }
}

// 模拟linux cat命令读取文件并打印出文件内容
const readFile = (filname) =>{
    return new IO(()=> fs.readFileSync(filname, 'utf-8') ) //延迟不纯的操作，保证readFile是一个纯函数
}

// x指的是读取文件后返回的文件内容
const print = (x)=>{
    return new IO(()=>{
        console.log(x)
        return x
    })
}

const cat = fp.flowRight(print, readFile)
// IO(IO(x))
// 第一个_value是print返回 new IO产生的， 返回结果也是一个function， 说明读取文件后返回的是一个函数，需要对改函数再取value的值
const r = cat('package.json')._value()._value()
console.log(r)